package cc.rengu.igas.opms.core.service.trans.quickpay;

import cc.rengu.igas.opms.common.constant.OpmsParamConstant;
import cc.rengu.igas.opms.common.enums.PassTypeEnum;
import cc.rengu.igas.opms.common.enums.RespCodeEnum;
import cc.rengu.igas.opms.common.enums.SignTokenTypeEnum;
import cc.rengu.igas.opms.common.enums.SignTypeEnum;
import cc.rengu.igas.opms.common.util.ParameterUtil;
import cc.rengu.igas.opms.core.model.SignCardInfoBean;
import cc.rengu.igas.opms.core.realize.SignCardInfoService;
import cc.rengu.igas.opms.core.realize.impl.SignCardInfoServiceImpl;
import cc.rengu.igas.opms.core.service.base.ManageService;
import cc.rengu.igas.opms.facade.base.BaseResponse;
import cc.rengu.igas.opms.facade.request.CardReSignRequest;
import cc.rengu.igas.opms.facade.response.CardReSignResponse;
import cc.rengu.igas.share.common.constant.TransCacheConstant;
import cc.rengu.igas.share.common.constant.UserSessionConstant;
import cc.rengu.igas.share.core.model.UserInfo;
import cc.rengu.igas.share.core.realize.UserService;
import cc.rengu.igas.share.core.realize.impl.UserServiceImpl;
import cc.rengu.oltp.service.base.ChannelBaseService;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.common.constant.TreeNodeConstant;
import cc.rengu.oltp.service.common.dao.MsgTemplateCfgMapper;
import cc.rengu.oltp.service.common.dao.NonFinanceTxnMapper;
import cc.rengu.oltp.service.common.dao.SignAcctInfoMapper;
import cc.rengu.oltp.service.common.dao.impl.MsgTemplateCfgMapperImpl;
import cc.rengu.oltp.service.common.dao.impl.NonFinanceTxnMapperImpl;
import cc.rengu.oltp.service.common.dao.impl.SignAcctInfoMapperImpl;
import cc.rengu.oltp.service.common.entity.*;
import cc.rengu.oltp.service.common.enums.*;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.model.BizResponse;
import cc.rengu.oltp.service.model.OrderInfo;
import cc.rengu.oltp.service.realize.*;
import cc.rengu.oltp.service.realize.impl.SmsServiceImpl;
import cc.rengu.oltp.service.realize.impl.SysParamServiceImpl;
import cc.rengu.oltp.utility.util.*;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 银行卡重新签约服务
 * 根据报文头中的业务类型判断调用的通道类型
 *
 * @author keyi
 * @modify by wangcheng
 * @date 2020/3/19.
 */
public class CardReSignService extends ManageService implements TransCustomImpl {

    @Override
    protected Object bizBeforeCust() throws Exception {
        CardReSignRequest cardReSignRequest = new CardReSignRequest();
        ConvertUtil.convertOutput(cardReSignRequest);
        //去掉参数的空格，并对金额进行格式化
        ParameterUtil.paramertTrimAndFormatAmt(cardReSignRequest);
        return cardReSignRequest;
    }

    @Override
    protected BizResponse bizProcessCust(Object request) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        CardReSignRequest cardReSignRequest = (CardReSignRequest) request;
        String instId = cardReSignRequest.getHeader().getInstId();
        String userId = cardReSignRequest.getUserId();
        String certType = cardReSignRequest.getCertType();
        String certNo = cardReSignRequest.getCertNo();
        String signTokenType = cardReSignRequest.getSignTokenType();
        String smsVerifySeqNum = cardReSignRequest.getSmsVerifySeqNum();
        String smsCode = cardReSignRequest.getSmsCode();
        String acctNo = cardReSignRequest.getAcctNo();
        BizResponse<BaseResponse> bizResponse = new BizResponse<>();
        bizResponse.setRspSysId(AppParamConstant.SYS_ID);
        String sysSeqNum = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM);

        /* Step1：获取用户信息 */
        UserService userService = new UserServiceImpl();
        UserInfo userInfo = userService.getUserInfo(instId, userId, cardReSignRequest.getHeader().getSession());
        if (null == userInfo) {
            rglog.error("获取用户信息失败!");
            throw new BizException(RespCodeEnum.USER_NOT_LOGIN_OR_SESSION_IS_EXPIRED.getRespCode(), RespCodeEnum.USER_NOT_LOGIN_OR_SESSION_IS_EXPIRED.getRespDesc());
        }
        String signInst = userService.getUserSignInst();
        String signType = userService.getUserSignType();

        /* Step2：校验三要素校验接口是否调用成功,防止越过三要素交易直接进行签约 */
        String authenticationFinishFlag = userService.getUserSessionValue(UserSessionConstant.AUTHENTICATION_FINISH_FLAG);
        if (!AppParamConstant.YES.equals(authenticationFinishFlag)) {
            rglog.info("交易流程跳跃，三要素校验接口未完成.<{}>", authenticationFinishFlag);
            throw new BizException(RespCodeEnum.NOT_SURP_TRANS_TYPE_ERROR.getRespCode(), RespCodeEnum.NOT_SURP_TRANS_TYPE_ERROR.getRespDesc());
        }

        /* step3.校验短信流水号 */
        NonFinanceTxn nonFinanceTxn;
        if (PassTypeEnum.BANK_SIAN.getPassCode().equals(signTokenType)) {
            rglog.info("本行快捷签约，校验验证码:<{}>", signTokenType);
            SmsService smsService = new SmsServiceImpl();
            smsService.verifySmsCode(instId, SmsTypeEnum.CARD_SIGN.getSmsType(), smsCode, smsVerifySeqNum);
        } else {
            rglog.info("非本行快捷签约，验证码验证流水号：<{}>", smsVerifySeqNum);
            NonFinanceTxnMapper nonFinanceTxnMapper = new NonFinanceTxnMapperImpl();
            nonFinanceTxn = nonFinanceTxnMapper.selectNonFinanceTxnInfoByPrimaryKey(instId, smsVerifySeqNum);
            if (nonFinanceTxn == null) {
                rglog.info("非金融流水表中无该请求短信验证码交易，instId:<{}>,smsVerifySeqNum:<{}>", instId, smsVerifySeqNum);
                throw new BizException(RespCodeEnum.VERIFICATION_CODE_INVALID.getRespCode(), RespCodeEnum.VERIFICATION_CODE_INVALID.getRespDesc());
            }
            GlobalTransUtil.setCacheValue(TransCacheConstant.ORIG_NON_FINANCE_TXN, nonFinanceTxn);
            GlobalTransUtil.setCacheValue(TransCacheConstant.SMS_CHANNEL_RELATION_KEY, nonFinanceTxn.getChannelOrderId());
        }

        /* Step4:检查签约信息 */
        SignAcctInfoMapper signAcctInfoMapper = new SignAcctInfoMapperImpl();
        List<SignAcctInfo> signAcctInfoList = signAcctInfoMapper.selectSignAcctInfoByCertInfo(instId, cardReSignRequest.getCertType(), cardReSignRequest.getCertNo());
        if (null != signAcctInfoList && !signAcctInfoList.isEmpty()) {
            signAcctInfoList = signAcctInfoList.stream().filter(item -> item.getSignType().equals(signType) && item.getSignInst().equals(signInst)).collect(Collectors.toList());
            /* Step4.1：判断该用户是否已经签约该银行卡 */
            Optional<SignAcctInfo> signAcctInfoOpt = signAcctInfoList.stream().filter(item -> item.getSignAcctNo().equals(acctNo) && item.getUserId().equals(cardReSignRequest.getUserId())).findFirst();
            if (signAcctInfoOpt.isPresent()) {
                /* 检查姓名是否一致 */
                if (!cardReSignRequest.getCardHoldName().equals(signAcctInfoOpt.get().getCardHoldName())) {
                    rglog.info("持卡人姓名不一致,上传持卡人姓名:<{}>,已存在的持卡人姓名:<{}>", cardReSignRequest.getCardHoldName(), signAcctInfoOpt.get().getCardHoldName());
                    throw new BizException(RespCodeEnum.CARD_NAME_DIFF.getRespCode(), RespCodeEnum.CARD_NAME_DIFF.getRespDesc());
                }
                rglog.info("当前卡:<{}>用户:<{}>已签约且签约状态为:<{}>", cardReSignRequest.getAcctNo(), userId, signAcctInfoOpt.get().getSignStatus());
                /* 先将签约信息放到交易缓存中，待签约成功后直接更新签约记录即可，不再插入新的签约记录 */
                GlobalTransUtil.setCacheValue(TransCacheConstant.SIGN_ACCT_INFO, signAcctInfoOpt.get());
            }
            /* Step4.2：生成当前签约账号的签约序号 */
            signAcctInfoList = signAcctInfoList.stream().filter(item -> AppParamConstant.YES.equals(item.getSignStatus())).collect(Collectors.toList());
            if (!signAcctInfoList.isEmpty()) {
                signAcctInfoList = signAcctInfoList.stream().sorted(Comparator.comparing(SignAcctInfo::getPayIndex).reversed()).collect(Collectors.toList());
                int payIndex = signAcctInfoList.get(0).getPayIndex() + 1;
                xmlTreeUtil.setXmlTreeIntValue("payIndex", payIndex);
            }
        } else {
            rglog.info("用户不存在签约信息(包括已经解约的签约数据),instId:<{}>,certType:<{}>,certNo:<{}>,signType:<{}>,signInst:<{}>", instId, certType, certNo, signType, signInst);
            throw new BizException(RespCodeEnum.GET_SIGN_INFO_ERROR.getRespCode(), RespCodeEnum.GET_SIGN_INFO_ERROR.getRespDesc());
        }

        /* step5:获取签约账号相关信息 */
        SignCardInfoService cardBinCheckService = new SignCardInfoServiceImpl();
        SignCardInfoBean signCardInfo = cardBinCheckService.getSignCardInfo(cardReSignRequest.getHeader().getInstId(), cardReSignRequest.getAcctNo(), cardReSignRequest.getSignTokenType());
        GlobalTransUtil.setCacheValue(TransCacheConstant.SIGN_CARD_INFO, signCardInfo);
        rglog.info("签约卡类型，acctType:<{}>", signCardInfo.getAcctType());

        /* step6:调用通道签约 */
        if (null == txnInfo.getChannelCallCfgList() || txnInfo.getChannelCallCfgList().isEmpty()) {
            rglog.error("<{}-{}>交易未配置交易通道服务调用配置信息！", txnInfo.getSrcTxnAuthCfg().getTxnNum(), txnInfo.getSrcTxnAuthCfg().getTxnName());
            throw new BizException(RespCodeEnum.CHANNEL_CONFIG_NOT_EXIST.getRespCode(), RespCodeEnum.CHANNEL_CONFIG_NOT_EXIST.getRespDesc());
        }
        List<ChannelCallCfg> channelCallCfgList = txnInfo.getChannelCallCfgList().stream().filter(item ->
                item.getCallIndex().equals(ChannelBaseService.FIRST_CHANNEL_CALL_INDEX)).collect(Collectors.toList());
        ChannelCallCfg channelCallCfg = channelCallSceneDiscern(cardReSignRequest, channelCallCfgList);
        Class channelClasz = Class.forName(channelCallCfg.getCallChannelImpl());
        ChannelBaseService channelBaseService = (ChannelBaseService) channelClasz.newInstance();
        channelBaseService.callService(txnInfo, null, channelCallCfg.getBizScene(), request);

        /* step7:创建或者更新用户信息,并更新用户会话信息 */
        boolean isGrantMchnt = "1".equals(platMchntInfo.getGrantCreditFlag());
        if (!isGrantMchnt && !SignTypeEnum.BANK_CLASS_SIGN.getSignTypeCode().equals(signType)) {
            rglog.debug("当前商户为非授信商户且签约等级不是行级:<{}>，先注销之前的用户信息:<{}>，然后再生成新的用户！", signType, userInfo.getUserId());
            userInfo.setUserStatus(OpmsParamConstant.USER_INFO_USER_STATUS_CANCEL);
            if (!userService.updateUserInfo(userInfo)) {
                rglog.info("更新用户状态为注销失败:{}", JSON.toJSONString(userInfo));
                bizResponse.setRespCode(RespCodeEnum.USERLOGIN_UPDATE_ERROR.getRespCode());
                bizResponse.setRespDesc(RespCodeEnum.USERLOGIN_UPDATE_ERROR.getRespDesc());
                return bizResponse;
            }
            //创建新用户
            userId = instId + DateUtil.getCurrentDate() + sysSeqNum.substring(sysSeqNum.length() - 8);
            userInfo.setUserId(userId);
            userInfo.setUserName(userInfo.getUserName());
            userInfo.setMobileNo(cardReSignRequest.getPhoneNo());
            userInfo.setCertType(cardReSignRequest.getCertType());
            userInfo.setCertNo(cardReSignRequest.getCertNo());
            userInfo.setUserStatus(OpmsParamConstant.USER_INFO_USER_STATUS_NORMAL);
            userInfo.setTransPasswordErrorTimes(0);
            userInfo.setTransPasswordSalt((instId + DateUtil.getCurrentDate() + sysSeqNum.substring(sysSeqNum.length() - 8)));
            rglog.debug("登记新的用户信息,userId:<{}>", userInfo.getUserId());
            if (!userService.registerUserInfo(userInfo)) {
                rglog.info("登记收银台用户信息表失败:{}", JSON.toJSONString(userInfo));
                bizResponse.setRespCode(RespCodeEnum.USERREG_INSERT_ERROR.getRespCode());
                bizResponse.setRespDesc(RespCodeEnum.USERREG_INSERT_ERROR.getRespDesc());
                return bizResponse;
            }
        } else {
            rglog.debug("授信商户或机构级签约:<{}>,不需要更新用户信息，保持使用之前的userId:<{}>", signType, userId);
            userInfo.setTransPasswordErrorTimes(0);
            userInfo.setTransPassword("");
            userInfo.setMobileNo(cardReSignRequest.getPhoneNo());
            userInfo.setTransPasswordSalt((instId + DateUtil.getCurrentDate() + sysSeqNum.substring(sysSeqNum.length() - 8)));
            if (!userService.updateUserInfo(userInfo)) {
                rglog.info("更新用户信息表失败:{}", JSON.toJSONString(userInfo));
                bizResponse.setRespCode(RespCodeEnum.USERLOGIN_UPDATE_ERROR.getRespCode());
                bizResponse.setRespDesc(RespCodeEnum.USERLOGIN_UPDATE_ERROR.getRespDesc());
                return bizResponse;
            }
        }
        userService.setUserSessionValue(instId + userInfo.getUserId(), JSON.toJSONString(userInfo));

        /* step8:设置重新签约的响应体 */
        CardReSignResponse cardReSignResponse = new CardReSignResponse();
        cardReSignResponse.setHeader(cardReSignRequest.getHeader());
        cardReSignResponse.setUserId(userInfo.getUserId());
        bizResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
        bizResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
        bizResponse.setResult(cardReSignResponse);
        return bizResponse;
    }

    @Override
    protected void bizAfterCust(Object response) throws Exception {
        BizResponse bizResponse = (BizResponse) response;
        CardReSignResponse cardReSignResponse = (CardReSignResponse) bizResponse.getResult();
        ConvertUtil.convertInput(cardReSignResponse);
    }

    @Override
    public ChannelCallCfg channelCallSceneDiscern(Object request, List<ChannelCallCfg> channelCallCfgList) throws Exception {
        CardReSignRequest cardReSignRequest = (CardReSignRequest) request;
        String bizType = cardReSignRequest.getHeader().getBizType();
        SignCardInfoBean signCardInfo = (SignCardInfoBean) GlobalTransUtil.getCacheValue(TransCacheConstant.SIGN_CARD_INFO);
        if (null == signCardInfo) {
            rglog.error("无法获取当前签约卡的签约相关信息!");
            return null;
        }
        //业务场景代码：00-本行借卡快捷签约,01-本行贷记卡快捷签约,02-银联无卡快捷支付签约,03-网联协议支付签约
        String bizScene = null;
        if ("00".equals(bizType)) {
            if (AcctTypeEnum.BANK_DEBIT.getAcctType().equals(signCardInfo.getAcctType())) {
                bizScene = "00";
            }
            if (AcctTypeEnum.BANK_CREDIT.getAcctType().equals(signCardInfo.getAcctType())) {
                bizScene = "01";
            }
        } else if ("01".equals(bizType)) {
            bizScene = "02";
        } else if ("02".equals(bizType)) {
            bizScene = "03";
        }
        String finalBizScene = bizScene;
        Optional<ChannelCallCfg> channelCallCfgOpt = channelCallCfgList.stream().filter(item -> item.getBizScene().equals(finalBizScene)).findFirst();
        return channelCallCfgOpt.orElse(null);
    }

    @Override
    public CheckResultEnum channelCallPreCheck(Object request, ChannelCallCfg channelCallCfg, OrderInfo orderInfo) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        CardReSignRequest cardReSignRequest = (CardReSignRequest) request;
        if ("02".equals(channelCallCfg.getBizScene()) || "03".equals(channelCallCfg.getBizScene())) {
            NonFinanceTxn nonFinanceTxn = (NonFinanceTxn) GlobalTransUtil.getCacheValue(TransCacheConstant.ORIG_NON_FINANCE_TXN);
            if (null == nonFinanceTxn) {
                rglog.error("银联无卡快捷或者网联协议支付签约，未查到发送短信流水，交易失败!");
                return CheckResultEnum.REFUSE;
            }
            //网联协议支付签约设置交易类别为0202
            if ("02".equals(channelCallCfg.getBizScene())) {
                xmlTreeUtil.setXmlTreeStringValue("trxCtgy", "0202");
            }
        }
        if (ChannelEnum.SMPS.getChannelType().equals(channelCallCfg.getCallChannelId()) &&
                "00450000000E01".equals(channelCallCfg.getCallChannelTxn())) {
            //获取短信模板
            MsgTemplateCfgMapper msgTemplateCfgMapper = new MsgTemplateCfgMapperImpl();
            MsgTemplateCfg msgTemplateCfg = msgTemplateCfgMapper.selectMsgTemplateCfgByTemplateType(channelCallCfg.getInstId(), TemplateTypeEnum.SMS_FAST_PAYMENT_SIGN_SUCC.getTemplateType());
            if (null == msgTemplateCfg) {
                msgTemplateCfg = msgTemplateCfgMapper.selectMsgTemplateCfgByTemplateType(AppParamConstant.DEFAULT_INSTID, TemplateTypeEnum.SMS_FAST_PAYMENT_SIGN_SUCC.getTemplateType());
                if (null == msgTemplateCfg) {
                    rglog.warn("未配置签约成功后向用户发送短信通知的短信模板,不发送短信，instId:<{}>", channelCallCfg.getInstId());
                    return CheckResultEnum.NEXT;
                }
            }
            //短信内容
            rglog.debug("短信模板代码:<{}>,短信模板内容:<{}>", msgTemplateCfg.getTemplateCode(), msgTemplateCfg.getTemplateDesc());
            String smsContent = parseSmsTemplateInfo(msgTemplateCfg.getTemplateDesc(), cardReSignRequest.getAcctNo());
            GlobalTransUtil.setCacheValue(TransCacheConstant.SMS_TEMPLATE_CODE, msgTemplateCfg.getTemplateCode());
            GlobalTransUtil.setCacheValue(TransCacheConstant.SMS_CONTENT, smsContent);
            List<String> phoneList = new ArrayList<>(Collections.singleton(cardReSignRequest.getPhoneNo()));
            GlobalTransUtil.setCacheValue(TransCacheConstant.SMS_PHONE_NO_LIST, phoneList);
        }
        return CheckResultEnum.PASSED;
    }

    @Override
    public TransStatusEnum channelCallResultProc(Object request, ChannelCallCfg channelCallCfg, TransStatusEnum transStatusEnum, Object channelResponse, OrderInfo needUpdateOrderInfo) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        CardReSignRequest cardReSignRequest = (CardReSignRequest) request;
        String instId = cardReSignRequest.getHeader().getInstId();
        String userId = cardReSignRequest.getUserId();
        String sessionId = cardReSignRequest.getHeader().getSession();
        if (TransStatusEnum.TRANS_SUCC.equals(transStatusEnum) && null != channelResponse) {
            if (ChannelEnum.SMPS.getChannelType().equals(channelCallCfg.getCallChannelId()) &&
                    "00".equals(channelCallCfg.getBizType()) && "0000".equals(channelCallCfg.getCallIndex())) {
                //本行卡签约时，将核心客户号更新到用户信息中
                String coreCustomerId = xmlTreeUtil.getXmlTreeStringValue("coreCustomerId");
                UserService userService = new UserServiceImpl();
                UserInfo userInfo = userService.getUserInfo(instId, userId, sessionId);
                if (null != userInfo && !StringUtil.isEmptyOrNull(coreCustomerId)) {
                    userInfo.getUserApexMap().put(UserSessionConstant.CORE_CUSTOMER_ID, coreCustomerId);
                    userService.setUserSessionValue(instId + userId, JSON.toJSONString(userInfo));
                    userService.updateUserInfo(userInfo);
                }
            } else if (ChannelEnum.ESB.getChannelType().equals(channelCallCfg.getCallChannelId()) ||
                    ChannelEnum.NCQS.getChannelType().equals(channelCallCfg.getCallChannelId()) ||
                    ChannelEnum.NUCC.getChannelType().equals(channelCallCfg.getCallChannelId())) {
                //获取银行设置的默认限额配置信息
                SysParamService sysParamService = new SysParamServiceImpl();
                SysParam singleSysParam = sysParamService.getSysParamInfo(channelCallCfg.getInstId(), OpmsParamConstant.OPMS_PARAM_TYPE, OpmsParamConstant.SINGLE_LIMIT_AMT);
                SysParam daySysParam = sysParamService.getSysParamInfo(channelCallCfg.getInstId(), OpmsParamConstant.OPMS_PARAM_TYPE, OpmsParamConstant.DAY_LIMIT_AMT);
                SysParam noPasswordParam = sysParamService.getSysParamInfo(channelCallCfg.getInstId(), OpmsParamConstant.OPMS_PARAM_TYPE, OpmsParamConstant.NO_PASSWORD_LIMIT_AMT);
                SysParam authLimitParam = sysParamService.getSysParamInfo(channelCallCfg.getInstId(), OpmsParamConstant.OPMS_SYS_PARAM, OpmsParamConstant.AUTH_LIMIT_AMT);
                SignCardInfoBean signCardInfo = (SignCardInfoBean) GlobalTransUtil.getCacheValue(TransCacheConstant.SIGN_CARD_INFO);
                SignAcctInfo signAcctInfo = (SignAcctInfo) GlobalTransUtil.getCacheValue(TransCacheConstant.SIGN_ACCT_INFO);
                SignAcctInfoMapper signAcctInfoMapper = new SignAcctInfoMapperImpl();
                if (null != signAcctInfo) {
                    //当前卡号已有签约记录，只更新里面的签约信息即可
                    signAcctInfo.setSingleLimitAmt(null == singleSysParam ? "" : singleSysParam.getParamValue());
                    signAcctInfo.setDayLimitAmt(null == daySysParam ? "" : daySysParam.getParamValue());
                    signAcctInfo.setNoPasswordAmt(null == noPasswordParam ? "" : noPasswordParam.getParamValue());
                    signAcctInfo.setAuthLimitAmt(null == authLimitParam ? "" : authLimitParam.getParamValue());
                    signAcctInfo.setPayIndex(xmlTreeUtil.getXmlTreeIntegerValue("payIndex"));
                    signAcctInfo.setUpdateTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
                    if (OpmsParamConstant.INT_ZERO != signAcctInfoMapper.updateSignAcctInfoBySignAcctNo(signAcctInfo)) {
                        rglog.info("根据第二索引更新签约信息数据失败，signAcctInfo:<{}>", JSONObject.toJSONString(signAcctInfo));
                        throw new BizException(RespCodeEnum.UPDATE_SIGN_ACCT_ERROR.getRespCode(), RespCodeEnum.UPDATE_SIGN_ACCT_ERROR.getRespDesc());
                    }
                } else {
                    signAcctInfo = new SignAcctInfo();
                    UserService userService = new UserServiceImpl();
                    String signInst = userService.getUserSignInst();
                    String signType = userService.getUserSignType();
                    if (null != signCardInfo) {
                        if (ChannelEnum.NCQS.getChannelType().equals(channelCallCfg.getCallChannelId()) || ChannelEnum.NUCC.getChannelType().equals(channelCallCfg.getCallChannelId())) {
                            String signNo = xmlTreeUtil.getXmlTreeStringValue("signNo");
                            signAcctInfo = generateSignAcctInfo(signNo, signType, signInst, signCardInfo.getAcctType(), cardReSignRequest, signCardInfo);
                        } else if (ChannelEnum.ESB.getChannelType().equals(channelCallCfg.getCallChannelId())) {
                            String signNo = DateUtil.getCurrentTimeStamp() + RandomUtil.getRandomInt();
                            xmlTreeUtil.setXmlTreeStringValue("signNo", signNo);
                            signAcctInfo = generateSignAcctInfo(signNo, signType, signInst, signCardInfo.getAcctType(), cardReSignRequest, signCardInfo);
                        }
                        signAcctInfo.setSingleLimitAmt(null == singleSysParam ? "" : singleSysParam.getParamValue());
                        signAcctInfo.setDayLimitAmt(null == daySysParam ? "" : daySysParam.getParamValue());
                        signAcctInfo.setNoPasswordAmt(null == noPasswordParam ? "" : noPasswordParam.getParamValue());
                        signAcctInfo.setAuthLimitAmt(null == authLimitParam ? "" : authLimitParam.getParamValue());
                        if (OpmsParamConstant.INT_ZERO != signAcctInfoMapper.insertSignAcctInfo(signAcctInfo)) {
                            rglog.info("插入签约信息失败，signAcctInfo:<{}>", JSONObject.toJSONString(signAcctInfo));
                            throw new BizException(RespCodeEnum.USER_REGISTER_ERROR.getRespCode(), RespCodeEnum.USER_REGISTER_ERROR.getRespDesc());
                        }
                    } else {
                        rglog.error("签约账号关联信息为空，业务处理异常!");
                        return TransStatusEnum.SYSTEM_REJECT;
                    }
                }
            }
        }
        return transStatusEnum;
    }

    /**
     * 生成签约实体
     *
     * @param signNo            签约协议号
     * @param signType          签约类型
     * @param signInst          签约主体
     * @param acctType          账户类型
     * @param cardReSignRequest 请求体
     * @return 签约实体
     * @throws Exception 异常
     */
    private SignAcctInfo generateSignAcctInfo(String signNo, String signType, String signInst, String acctType, CardReSignRequest cardReSignRequest, SignCardInfoBean opmsBankCodeInfo) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        SignAcctInfo signAcctInfo = new SignAcctInfo();
        ConvertUtil.convertOutput(signAcctInfo);
        signAcctInfo.setUserId(cardReSignRequest.getUserId());
        signAcctInfo.setSignToken(opmsBankCodeInfo.getBankBranchCode() + "|" + signNo);
        signAcctInfo.setSignTokenType(cardReSignRequest.getSignTokenType());
        signAcctInfo.setSignTokenInst(OpmsParamConstant.DEFAULT_SIGN_TOKEN_INST);
        signAcctInfo.setSignType(signType);
        signAcctInfo.setSignInst(signInst);
        signAcctInfo.setCardHoldName(cardReSignRequest.getCardHoldName());
        signAcctInfo.setCertType(cardReSignRequest.getCertType());
        signAcctInfo.setCertNo(cardReSignRequest.getCertNo());
        signAcctInfo.setSignAcctType(acctType);
        signAcctInfo.setPayIndex(xmlTreeUtil.getXmlTreeIntegerValue("payIndex"));
        signAcctInfo.setSignAcctNo(cardReSignRequest.getAcctNo());
        signAcctInfo.setReserveMobileNo(cardReSignRequest.getPhoneNo());
        signAcctInfo.setSignBankNo(opmsBankCodeInfo.getBankBranchCode());
        signAcctInfo.setSignBankName(opmsBankCodeInfo.getBankName());
        signAcctInfo.setSignDate(DateUtil.getCurrentDate());
        signAcctInfo.setSignStatus(AppParamConstant.YES);
        signAcctInfo.setSignSysSeqNum(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM));
        signAcctInfo.setSignStatus(OpmsParamConstant.OPMS_PARAM_YES);
        signAcctInfo.setSignExpiryDate("20991231");
        signAcctInfo.setCreateTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
        return signAcctInfo;
    }

    /**
     * 动态解析短信模板生成短信内容
     *
     * @param templateDesc 短信模板内容
     * @return 短信内容
     */
    private String parseSmsTemplateInfo(String templateDesc, String acctNo) {
        StringBuilder stringBuilder = new StringBuilder();
        while (!StringUtil.isEmptyOrNull(templateDesc) && templateDesc.contains("[")) {
            int startIndex = templateDesc.indexOf("[");
            stringBuilder.append(templateDesc, 0, startIndex);
            templateDesc = templateDesc.substring(startIndex + 1);
            int endIndex = templateDesc.indexOf("]");
            stringBuilder.append(acctNo.substring(acctNo.length() - 4));
            templateDesc = templateDesc.substring(endIndex + 1);
        }
        stringBuilder.append(templateDesc);
        return stringBuilder.toString();
    }
}
